Lasers passively mode-locked by means of saturable absorbers have a tendency to Q-switched mode-locking (QML). Usually, this is not the desired mode of operation and has to be avoided by careful design. This is not always easy, especially not for the low pulse energies typically associatedd with very high pulse-repetition rates.

In the following, I summarize the dynamics of such a laser and show the criterion for stable mode locking (i.e. not QML).

Laser Dynamics

The following differential equation describes the dynamics of a passively mode-locked (see, e.g., C. Hönninger et al., J. Opt. Soc. Am. B/Vol. 16, No. 1, 1999):

$$\begin{align*} \dot{P} &= \frac{g - l - q_P(S)}{T_R} P \\ \dot{g} &= -\frac{g}{\tau_L} + \frac{\eta \cdot P_P}{E_{sat,L}} - \frac{P \cdot g}{E_{sat,L}} \\ q_P(S) &= \frac{\Delta R}{S} \left(1 - e^{-S} \right) \end{align*}$$

,

where $S = \frac{E_P}{E_{sat,A}} = \frac{P \cdot T_R}{E_{sat,A}}$.

Let's set this up in sympy but let's - for the time being - ignore that $q_P$ is a function of $P(t)$:


In [1]:
import sympy as sym
from IPython.display import display
sym.init_printing(use_latex='mathjax')

# Variables
P, g, PP, qP = sym.symbols('P g P_P q_P', real=True)
l = sym.symbols('l', real=True)
DR = sym.Symbol('\Delta R', real=True)
EsatL, tauL, TR, eta, EsatA = sym.symbols('E_{satL} tau_L T_R eta E_{satA}',
                                          real=True)

# Differential Equations
laserEq = [sym.Eq((g - l - qP) / TR * P),
           sym.Eq(-g / tauL + eta * PP / EsatL - P * g / EsatL)]
display(*laserEq)


$$\frac{P}{T_{R}} \left(g - l - q_{P}\right) = 0$$
$$- \frac{g}{\tau_{L}} - \frac{P g}{E_{{satL}}} + \frac{P_{P} \eta}{E_{{satL}}} = 0$$

Steady-State

Next, we linearize these equations around their steady-state. The steady-state gain $g_{st}$ and intra-cavity power $P_{st}$ are:


In [2]:
PP0 = sym.Symbol('P_{P0}')
gst_, Pst_ = sym.solve(laserEq, (g, P))[1]

Pst_ = Pst_.subs(PP, PP0)

display(sym.Eq(sym.Symbol('g_{st}'), gst_),
        sym.Eq(sym.Symbol('P_{st}'), Pst_.subs(g, sym.Symbol('g_{st}'))))


$$g_{{st}} = l + q_{P}$$
$$P_{{st}} = \frac{1}{\tau_{L} \left(l + q_{P}\right)} \left(- E_{{satL}} l - E_{{satL}} q_{P} + P_{{P0}} \eta \tau_{L}\right)$$

To determine $q_P$, we multiply the $P_{st}$ equation by $g_{st}$ on both sides and substitute $g_{st}$:


In [3]:
qPEq = sym.Eq(P * gst_, Pst_ * g)
qPEq.subs(P, sym.Symbol('P_{st}'))


Out[3]:
$$P_{{st}} \left(l + q_{P}\right) = \frac{g}{\tau_{L} \left(l + q_{P}\right)} \left(- E_{{satL}} l - E_{{satL}} q_{P} + P_{{P0}} \eta \tau_{L}\right)$$

Now we re-write both sides as functions of $S$ to obtain an equation for the steady-state $S$ parameter:


In [4]:
S = sym.symbols('S', real=True)
qPEq = qPEq.subs(qP, DR / S * (1 - sym.exp(-S))).subs(P, S * EsatA / TR)
sym.simplify(qPEq)


Out[4]:
$$\frac{E_{{satA}}}{T_{R}} \left(S l e^{S} + \Delta R \left(e^{S} - 1\right)\right) e^{- S} = - \frac{g \left(E_{{satL}} \Delta R \left(e^{S} - 1\right) + S \left(E_{{satL}} l - P_{{P0}} \eta \tau_{L}\right) e^{S}\right)}{\tau_{L} \left(S l e^{S} + \Delta R \left(e^{S} - 1\right)\right)}$$

Unfortunately, it turns out that this equation is rather hard to solve symbolically:


In [5]:
sym.solve(qPEq, S)


---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-5-c8970a9a2078> in <module>()
----> 1 sym.solve(qPEq, S)

/home/adrian/.local/lib/python3.4/site-packages/sympy/solvers/solvers.py in solve(f, *symbols, **flags)
    907     ###########################################################################
    908     if bare_f:
--> 909         solution = _solve(f[0], *symbols, **flags)
    910     else:
    911         solution = _solve_system(f, symbols, **flags)

/home/adrian/.local/lib/python3.4/site-packages/sympy/solvers/solvers.py in _solve(f, *symbols, **flags)
   1412     if result is False:
   1413         raise NotImplementedError(msg +
-> 1414         "\nNo algorithms are implemented to solve equation %s" % f)
   1415 
   1416     if flags.get('simplify', True):

NotImplementedError: multiple generators [S, exp(S)]
No algorithms are implemented to solve equation E_{satA}*S*(l + \Delta R*(1 - exp(-S))/S)/T_R - g*(-E_{satL}*l - E_{satL}*\Delta R*(1 - exp(-S))/S + P_{P0}*eta*tau_L)/(tau_L*(l + \Delta R*(1 - exp(-S))/S))

Linearization

Next, we rewrite the laser equations in terms of deviations from the steady-state:

$$\begin{align*} P &= P_{st} + \delta P \\ g &= g_{st} + \delta g \\ P_P &= P_{P,0} + \delta P_P \end{align*}$$

In [ ]:
dP = sym.Symbol('\delta P', real=True)
dg = sym.Symbol('\delta g', real=True)
dPP = sym.Symbol('\delta P_P', real=True)
dqPdEP = sym.Symbol("q'_P", real=True)
Pst, gst = sym.symbols('P_{st} g_{st}', real=True)

deviationEq = ['', '']
deviationEq[0] = sym.Eq(sym.Symbol('\delta Pdot'), laserEq[0].lhs)
deviationEq[1] = sym.Eq(sym.Symbol('\delta gdot'), laserEq[1].lhs)

deviationEq = [eq.subs([(P, Pst + dP),
                        (g, gst + dg),
                        (PP, PP0 + dPP),
                        (qP, qP + dP * TR * dqPdEP)]) for eq in deviationEq]
display(*sym.simplify(deviationEq))

Next, we drop all higher order term. Unfortunately, sympy does not (yet?) support multivariate series expansion. Therefore, we solve the problem by introducing a helper variable $\delta x$ which is subsequently dropped.


In [ ]:
dx = sym.Symbol('\delta x', real=True)
lin = [eq.rhs for eq in deviationEq]
lin = [expr.subs([(dg, dg * dx), (dP, dP * dx)]) for expr in lin]
lin = [expr.series(dx, x0=0, n=2).removeO().subs(dx, 1) for expr in lin]
lin = [sym.collect(sym.collect(eq, dP), dg) for eq in lin]
linEq = [sym.Eq(sym.Symbol('\delta Pdot'), lin[0]),
         sym.Eq(sym.Symbol('\delta gdot'), lin[1])]
linEq

There we are. However, this does not look linear. There seem to be unexpected constant terms. It turns out that these are zero due to the steady-state condition:


In [ ]:
# Replace steady-state symbols with their corresponding expressions:
linEq[0] = sym.simplify(linEq[0].subs(gst, gst_))
linEq[1] = linEq[1].subs([(Pst, Pst_), (gst, gst_)])

# Rewrite in steady-state symbols for clarity:
linEq[1] = linEq[1].subs(PP0, sym.solve(sym.Eq(Pst, Pst_), PP0)[0])
linEq[1] = linEq[1].subs(l, sym.solve(sym.Eq(gst, gst_), l)[0])
linEq[1] = sym.simplify(linEq[1])

linEq

Now, we can rewrite this in handy matrix-notation in state-space form as follows:


In [ ]:
A = sym.zeros(2, 2)
for i in range(2):
    for j in range(2):
        col = [dP, dg][j]
        A[i, j] = sym.collect(linEq[i].rhs.expand(), col, evaluate=False)[col]

B = sym.zeros(2, 1)
for i in range(2):
    try:
        B[i, 0] = sym.collect(linEq[i].rhs.expand(), dPP, evaluate=False)[dPP]
    except KeyError:
        B[i, 0] = 0

x = sym.MatrixSymbol('x', 2, 1)
u = sym.MatrixSymbol('u', 1, 1)

stateEq = sym.Eq(sym.MatrixSymbol('xdot', 2, 1), A * x + B * u)
stateEq

where $\vec{x} = \left[ \delta P, \delta g \right]^T$ and $\vec u = [\delta P_P]$. And to be complete, we add the output equation:


In [ ]:
y = sym.MatrixSymbol('y', 1, 1)
Toc = sym.Symbol('T_{oc}', real=True)
C = sym.Matrix([[Toc, 0]])
outputEq = sym.Eq(y, C*x)
outputEq

where $\vec y$ is $\left[ P_{out} \right]$.

Stability

It is now straightforward to discuss the stability of the system at its steady-state. The system is stable if the eigenvalue of $A$ all are in the left half of the complex plane. The eigenvalues of a 2 x 2 matrix

$$ \left( \begin{array}{ccc} \alpha & \beta \\ -\gamma & -\epsilon \end{array} \right) $$

are:


In [ ]:
alpha, beta, gamma, epsilon = sym.symbols('alpha beta gamma epsilon', real=True)
M = sym.Matrix([[alpha, beta], [-gamma, -epsilon]])
M.eigenvals()

In the case of solid-state lasers, the radicand is negative, leading to relaxation oscillations. If $\alpha - \epsilon < 0$, these oscillations are damped, and the laser is stably mode locking. This conditions translates to


In [ ]:
A[0, 0] + A[1, 1] < 0

That's it for now. As soon as I understand limits and assumptions in sympy I may add the useful simplification for strongly saturated absorbers. The result will be:

$$ E_P^2 > E_{satL} E_{satA} \Delta R $$